#include <windows.h>
#include <Iphlpapi.h>
#include <stdio.h>
#include <tchar.h>

#include <stdlib.h>  
#include <assert.h>  
#include <io.h>
#include <direct.h>

#include <string.h>
#include <ctime>

#include <wincrypt.h>

#include <string>
#include <iostream>
using namespace std;

#pragma once

#pragma comment(lib,"Iphlpapi")

#define DFP_GET_VERSION 0x00074080
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088

#define IDE_ATAPI_IDENTIFY 0xA1
#define IDE_ATA_IDENTIFY 0xEC
#define IDENTIFY_BUFFER_SIZE 512
void getMac(char *szMac);
void GetCpuID(char *szCpuid);
bool encrypt(char *csBuffer, char *csEncrypt);
void getRandomStr(char *strRand);
int main(int argc, char **argv)
{
	FILE *pf = fopen("./license.dat", "w");  

	assert(NULL != pf);  
	if (NULL == pf)  
		return -1;
	if (argc < 2)
	{
		printf("usage:%s  <macaddress>\n", argv[0]);
		return -2;
	}

	std::string bufMac = argv[1];

	char buf[256] = {'\0'};
	sprintf_s(buf,256,"%s", bufMac.c_str());
	char crystr[256] = {'\0'};
	encrypt(buf, crystr);
	char strRand[256] = {'\0'};
	getRandomStr(strRand);
	memset(buf,0,sizeof(buf));
	sprintf_s(buf,256,"%s%s", strRand,crystr);
	
	fprintf(pf, "%s", buf);   

	fclose(pf); 

	return 0;
}

bool encrypt(char *csBuffer, char *csEncrypt)
{
	HCRYPTPROV hCryptProv; 
	HCRYPTHASH hHash; 
	BYTE bHash[0x7f]; 
	DWORD dwHashLen= 16;  
	DWORD cbContent= strlen(csBuffer); 
	BYTE* pbContent= (BYTE*)csBuffer; 


	bool bRet = true;
	if(CryptAcquireContext(&hCryptProv, 
		NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) 
	{

		if(CryptCreateHash(hCryptProv, 
			CALG_MD5,	
			0, 0, &hHash)) 
		{
			if(CryptHashData(hHash, pbContent, cbContent, 0))
			{

				if(CryptGetHashParam(hHash, HP_HASHVAL, bHash, &dwHashLen, 0)) 
				{
					
					memset(csEncrypt, 0, cbContent);
					char tmp[260];
					for (int i = 0; i<16; i++)
					{
						sprintf_s(tmp, "%02x", bHash[i]);
						strcat(csEncrypt, tmp);
					}

				}
				else 
				{
					printf("Error getting hash param \n"); 
					bRet = false;
				}

			}
			else 
			{
				printf("Error hashing data \n"); 
				bRet = false;
			}
			CryptDestroyHash(hHash); 
		}
		else 
		{
			printf( "Error creating hash \n"); 
			bRet = false;
		}
		CryptReleaseContext(hCryptProv, 0); 

	}
	else 
	{
		printf( "Error acquiring context \n"); 
		bRet = false;
	}

	return bRet;


}void getRandomStr(char *strRand)
{
	const int LEN = 37; 
	char arrCharElem[LEN] = {'0', '1', '2','3','4','5','6','7','8','9',
		'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
		'p','q','r','s','t','u','v','w','x','y','z'};
	char tempstr[4] = {'\0'};
	srand((unsigned)time(0));
	int index = 0;
	for (int i = 0; i < 3; ++i)
	{
		index = rand() % 36;            
		tempstr[i] = arrCharElem[index];
	}
	strcpy(strRand,tempstr);

}